﻿using HDJ.Framework.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

namespace HDJ.Framework.Core
{
    public class AssetBundleEditorWindow : EditorWindow
    {

        [MenuItem("Tool/AssetBundle资源打包(1100)", priority = 1100)]
        static void OpenWindow()
        {
            AssetBundleEditorWindow win = GetWindow<AssetBundleEditorWindow>();
            win.autoRepaintOnSceneChange = true;
            win.wantsMouseMove = true;
            FocusWindowIfItsOpen<AssetsPoolEditorWindow>();
            win.Init();
        }
        private const string ResourcesAssetPath = "Assets/Resources/";
        private const string StreamingAssetsPath = "Assets/StreamingAssets";

        private string AssetBundlesOutputPath = StreamingAssetsPath;
        string settingDataPath = "Others/AssetBundleSettingData.txt";
        private Color oldGUIColor;
        private string platformFolderName = "";
        private void Init()
        {
            oldGUIColor = GUI.color;
            AssetBundlesOutputPath = StreamingAssetsPath;

            if (!Directory.Exists(ResourcesAssetPath))
            {
                Directory.CreateDirectory(ResourcesAssetPath);
            }
            RuntimePlatform runtimePlatform = AssetBundleBuildUtils.BuildTarget2RuntimePlatform(EditorUserBuildSettings.activeBuildTarget);
            platformFolderName = UnityExtendUtils.GetPlatformFolderName(runtimePlatform);

            AssetBundlesOutputPath += "/" + platformFolderName;
            if (!Directory.Exists(AssetBundlesOutputPath))
            {
                Directory.CreateDirectory(AssetBundlesOutputPath);
            }

            if (File.Exists(ResourcesAssetPath + settingDataPath))
            {
                string json = FileUtils.LoadTextFileByPath(ResourcesAssetPath + settingDataPath);
                settingData = JsonUtils.FromJson<AssetBundleInfo>(json);
            }
            else
            {
                settingData = new AssetBundleInfo();
            }

        }
        void OnEnable()
        {
            Init();
        }

        private void SaveAssetBundleInfo()
        {
            string json = JsonUtils.ToJson(settingData);
            FileUtils.CreateTextFile(ResourcesAssetPath + settingDataPath, json);
            AssetDatabase.Refresh();
        }
        private AssetBundleInfo settingData;


        private int toolbarOption = 0;
        private string[] toolbarTexts = { "AssetBundle", "更新包" };

        //private int toolbarOptionSec = 0;
        //private string[] toolbarTextsSec = { "预加载文件" };

        void OnGUI()
        {

            toolbarOption = GUILayout.Toolbar(toolbarOption, toolbarTexts, GUILayout.Width(Screen.width));
            switch (toolbarOption)
            {
                case 0:
                    AssetBundleMainGUI();
                    break;
                //case 1:
                //    GUILayout.Space(10);
                //    GUILayout.BeginHorizontal();
                //    GUILayout.FlexibleSpace();
                //    toolbarOptionSec = GUILayout.Toolbar(toolbarOptionSec, toolbarTextsSec, GUILayout.Width(Screen.width - 40));
                //    GUILayout.FlexibleSpace();
                //    GUILayout.EndHorizontal();

                //    switch (toolbarOptionSec)
                //    {
                //        case 0:
                //            GUILayout.Space(10);
                //            SetPreLoadFileGUI();
                //            break;

                //    }
                //    break;
                case 1:
                    BackUpAndUpdateGUI();
                    break;

            }

        }

        //#region 预加载文件选择
        //TreeModelController<FileData> preLoadFileData;
        //private Vector2 pos1 = Vector2.zero;
        //private Vector2 pos4 = Vector2.zero;
        //private string[] tempAllFilePath;
        //void SetPreLoadFileGUI()
        //{

        //    GUILayout.Space(7);
        //    GUILayout.BeginHorizontal();
        //    GUILayout.FlexibleSpace();
        //    if (GUILayout.Button("Refresh", GUILayout.Width(60)))
        //    {
        //        preLoadFileData = null;
        //        return;
        //    }
        //    GUILayout.EndHorizontal();
        //    GUILayout.Space(5);
        //    if (preLoadFileData == null)
        //    {
        //        tempAllFilePath = PathUtils.GetDirectoryFilePath(ResourcesAssetPath);
        //        tempAllFilePath = PathUtils.RemovePathWithEnds(tempAllFilePath, new string[] { ".meta" });
        //        preLoadFileData = EditorDrawFileDirectory.GetFileDirectoryInfo(tempAllFilePath, true);

        //        UpdatePreLoadFileData(preLoadFileData);
        //    }
        //    GUILayout.Label("选择预加载文件：");
        //    pos1 = GUILayout.BeginScrollView(pos1, "box");
        //    EditorDrawFileDirectory.DrawFileDirectory(preLoadFileData, ShowFileDirectoryType.ShowAllFile, null, null, true, PreLoadChooseCallBack);

        //    GUILayout.EndScrollView();

        //    GUILayout.Space(8);
        //    GUILayout.Label("选中的文件路径：");
        //    pos4 = GUILayout.BeginScrollView(pos4, "box");
        //    foreach (string p in settingData.preLoadResPaths)
        //    {
        //        GUILayout.BeginHorizontal("box");
        //        if (!OtherUtils.ArrayContains(tempAllFilePath, p))
        //            GUI.color = Color.red;
        //        GUILayout.Label("预加载路径:" + p);
        //        if (GUI.color == Color.red)
        //        {
        //            GUILayout.FlexibleSpace();
        //            GUILayout.Label("文件不存在");
        //        }
        //        GUI.color = oldGUIColor;
        //        GUILayout.EndHorizontal();
        //        GUILayout.Space(4);
        //    }
        //    GUILayout.EndScrollView();
        //    GUILayout.Space(10);
        //    if (GUILayout.Button("移除不存在预加载文件路径"))
        //    {
        //        List<string> tList = new List<string>();
        //        foreach (string p in settingData.preLoadResPaths)
        //        {
        //            if (!OtherUtils.ArrayContains(tempAllFilePath, p))
        //            {
        //                tList.Add(p);
        //            }
        //        }

        //        foreach (string p in tList)
        //        {
        //            settingData.preLoadResPaths.Remove(p);
        //        }
        //    }
        //}
        //void UpdatePreLoadFileData(TreeModelController<FileData> data)
        //{
        //    data.ListForeachNode((n) =>
        //    {
        //        if (settingData.preLoadResPaths.Contains(n.relativeRootPath))
        //            n.isChoose = true;
        //        return true;
        //    });
        //}
        //void PreLoadChooseCallBack(FileData data)
        //{
        //    if (data.isDirectory)
        //    {
        //        data.isChoose = false;
        //        return;
        //    }
        //    if (data.isChoose)
        //    {
        //        settingData.preLoadResPaths.Add(data.relativeRootPath);
        //    }
        //    else
        //    {
        //        settingData.preLoadResPaths.Remove(data.relativeRootPath);
        //    }
        //}
        //#endregion


        void AssetBundleMainGUI()
        {
            GUILayout.Space(7);
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            GUILayout.EndHorizontal();
            GUILayout.Space(5);
            GUILayout.BeginVertical("box");
            settingData.gameName = PlayerSettings.productName;
            settingData.gameVersion = PlayerSettings.bundleVersion;

            GUILayout.Label("游戏名字 :" + settingData.gameName);

            GUILayout.Label("游戏版本 :" + settingData.gameVersion);
            settingData.assetBundleVersion = (int)EditorDrawGUIUtil.DrawBaseValue("AssetBundle版本", settingData.assetBundleVersion);

            GUILayout.EndVertical();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("移除StreamingAssets文件夹"))
            {
                if (Directory.Exists(AssetBundlesOutputPath))
                {
                    Directory.Delete(AssetBundlesOutputPath, true);
                    AssetDatabase.Refresh();
                }
            }
            GUILayout.Space(7);
            if (GUILayout.Button("清除BundleName"))
            {
                long start = DateTime.Now.Ticks;
                Debug.Log("开始设置");
                AssetBundleBuildUtils.ClearAssetBundlesName();
                Debug.Log("结束，用时：" + ((DateTime.Now.Ticks - start) / 10000 / 1000f)+"s");
            }
            GUILayout.Space(7);
            if (GUILayout.Button("生成BundleName"))
            {
                long start = DateTime.Now.Ticks;
                Debug.Log("开始设置");
                // AssetBundleBuildUtils.ClearAssetBundlesName();
                AssetBundleBuildUtils.SetAllResourceBundleName(ResourcesAssetPath, null);
                Debug.Log("结束，用时：" + ((DateTime.Now.Ticks - start) / 10000 / 1000f)+"s");
            }
            if (GUILayout.Button("生成依赖包"))
            {
                SaveAssetBundleInfo();

                AssetBundleBuildUtils.ClearAssetBundlesName();
                AssetBundleBuildUtils.SetAllResourceBundleName(ResourcesAssetPath, null);
                AssetBundleBuildUtils.BuildAssetBundle(AssetBundlesOutputPath);
                //AssetBundleBuildUtils.ClearAssetBundlesName();
                AssetBundleBuildUtils.CreateBundleVersionFile(AssetBundlesOutputPath, settingData);

               // AssetBundleBuildUtils.CreateOneFileBundle(AssetBundlesOutputPath, AssetBundlesOutputPath + "/" + UpdateAssetsConst.AssetBundleInfoFileName);
                AssetBundleBuildUtils.CreateAllResPathInfo_StreamingAssets(AssetBundlesOutputPath, new string[] { UpdateAssetsConst.EndsWith_assetbundle, ".manifest", "" }, platformFolderName);
                AssetBundleBuildUtils.CreateAllResMD5AndPath(AssetBundlesOutputPath, new string[] { UpdateAssetsConst.EndsWith_assetbundle, ".manifest", "" }, platformFolderName);

                AssetBundleBuildUtils.CreateOneFileBundle(AssetBundlesOutputPath, AssetBundlesOutputPath + "/" + UpdateAssetsConst.PathFileName);
                AssetDatabase.Refresh();


                if (EditorUtility.DisplayDialog("提示", "Bundle打包成功", "OK"))//显示对话框  
                {
                    isCanCreatePackage = Init_Update();
                }
            }
            GUILayout.Space(7);

        }



        #region 备份，跟新包

        private VersionControlInfo versionControlInfo = new VersionControlInfo();
        private string updatePackPathDic = "";
        private int lastAssetBundleVersion = -1;
        private bool isCanCreatePackage = false;
        private Dictionary<string, string> changeFileDic = new Dictionary<string, string>();

        private bool Init_Update()
        {
            changeFileDic = new Dictionary<string, string>();

            lastAssetBundleVersion = -1;
            updatePackPathDic = Application.dataPath.Replace("Assets", UpdateAssetsConst.UpdatePackageEditorFolderName) + "/" + platformFolderName + "/" + settingData.gameVersion;

            if (File.Exists(updatePackPathDic + "/" + UpdateAssetsConst.VersionControlInfoFileName))
            {
                //获得更新包的json数据
                string temp = FileUtils.LoadTextFileByPath(updatePackPathDic + "/" + UpdateAssetsConst.VersionControlInfoFileName);
                versionControlInfo = JsonUtils.FromJson<VersionControlInfo>(temp);
                if (versionControlInfo == null)
                    versionControlInfo = new VersionControlInfo();
            }
            else
            {
                versionControlInfo = new VersionControlInfo();
            }

            //创建存放更新的路径目录
            if (!Directory.Exists(updatePackPathDic))
            {
                Directory.CreateDirectory(updatePackPathDic);
                FileUtils.CopyDirectory(AssetBundlesOutputPath, updatePackPathDic + "/" + settingData.assetBundleVersion);

            }
            else
            {
                //获得目标路径下的所有文件夹（存放以往版本的资源目录）
                string[] pathDics = Directory.GetDirectories(updatePackPathDic);
                if (pathDics.Length > 0)
                {
                    //获得上一次资源版本
                    List<int> nums = new List<int>();
                    foreach (var item in pathDics)
                    {
                        int n = int.Parse(Path.GetFileNameWithoutExtension(item));
                        nums.Add(n);
                    }

                    lastAssetBundleVersion = GetMaxNumber(nums);

                    if (lastAssetBundleVersion >= settingData.assetBundleVersion)
                        return false;
                    else
                    {
                        string backUpPathDic = updatePackPathDic + "/" + lastAssetBundleVersion;

                        //获取上个版本和当前版本的文件MD5进行对比
                        string backUpMD5FileData = FileUtils.LoadTextFileByPath(backUpPathDic + "/" + UpdateAssetsConst.PathMD5FileName);
                        string nowMD5FileData = FileUtils.LoadTextFileByPath(AssetBundlesOutputPath + "/" + UpdateAssetsConst.PathMD5FileName);

                        changeFileDic = GetChangeFileDatas(backUpMD5FileData, nowMD5FileData);
                        if (changeFileDic.Count > 0)
                        {

                            return true;
                        }
                    }
                }
            }
            return false;
        }


        void BackUpAndUpdateGUI()
        {
            GUILayout.Space(7);
            GUILayout.Box("Game Version : " + PlayerSettings.bundleVersion);

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Refresh", GUILayout.Width(60)))
            {
                isCanCreatePackage = Init_Update();
            }
            GUILayout.EndHorizontal();



            GUILayout.Space(4);

            EditorDrawGUIUtil.DrawScrollView(changeFileDic, () =>
             {
                 GUILayout.Label("变化文件名 ：");
                 foreach (var item in changeFileDic.Keys)
                 {
                     GUILayout.Label("FileName : " + item);
                 }
                 GUILayout.Space(5);
                 GUILayout.Box("更新包 :");
                 foreach (var item in versionControlInfo.assetBundleVersions)
                 {
                     GUILayout.BeginHorizontal("box");
                     GUILayout.Label("更新包版本：" + item.ToString());
                     if (GUILayout.Button("Delete", GUILayout.Width(60)))
                     {

                         if (EditorUtility.DisplayDialog("警告", "是否删除该更新版本？", "是", "取消"))
                         {
                             versionControlInfo.assetBundleVersions.Remove(item);
                             string tempP = updatePackPathDic + "/" + item + ".zip";
                             FileUtils.DeleteFile(tempP);
                             Directory.Delete(updatePackPathDic + "/" + item, true);

                             SaveVersionControlInfo();

                             isCanCreatePackage = Init_Update();
                             return;
                         }
                     }

                     GUILayout.EndHorizontal();
                     GUILayout.Space(4);
                 }
             });




            GUILayout.FlexibleSpace();
            if (!isCanCreatePackage)
            {
                GUI.color = Color.red;
                GUILayout.Label("无文件更新！");
                GUI.color = Color.white;
            }

            if (isCanCreatePackage && GUILayout.Button("Create Package"))
            {
                versionControlInfo.assetBundleVersions.Add(settingData.assetBundleVersion);
                SaveVersionControlInfo();

                CreateUpdatePack(changeFileDic, updatePackPathDic, settingData.assetBundleVersion + ".zip");

                FileUtils.CopyDirectory(AssetBundlesOutputPath, updatePackPathDic + "/" + settingData.assetBundleVersion);
                isCanCreatePackage = Init_Update();

                EditorUtility.DisplayDialog("提示", "生成更新包成功！", "是");
            }

            GUILayout.Space(10);
        }

        private int GetMaxNumber(List<int> list)
        {
            int num = -1;
            foreach (var item in list)
            {
                if (item > num)
                    num = item;
            }

            return num;
        }


        private void SaveVersionControlInfo()
        {
            string json = JsonUtils.ToJson(versionControlInfo);
            FileUtils.CreateTextFile(updatePackPathDic + "/" + UpdateAssetsConst.VersionControlInfoFileName, json);
        }

        private Dictionary<string, string> GetChangeFileDatas(string oldData, string newData)
        {
            Dictionary<string, string> resDic = new Dictionary<string, string>();

            if (string.IsNullOrEmpty(oldData))
                return resDic;
            Dictionary<string, string> olderDic = JsonUtils.FromJson<Dictionary<string, string>>(oldData);
            Dictionary<string, string> newDic = JsonUtils.FromJson<Dictionary<string, string>>(newData);

            //Debug.Log("olderDic :" + olderDic.Count);
            //Debug.Log("newDic : " + newDic.Count);
            Dictionary<string, string> paths = AssetBundleBuildUtils.GetPathFileData(AssetBundlesOutputPath + "/PathFile.txt");

            foreach (string key in newDic.Keys)
            {
                if (!olderDic.ContainsKey(key))
                {
                    //Debug.Log("Key :"+key+"  value :" + newDic[key]);
                    resDic.Add(key, paths[key]);
                }
                else
                {
                    if (olderDic[key] != newDic[key])
                        resDic.Add(key, paths[key]);
                }
            }
            return resDic;
        }
        void CreateUpdatePack(Dictionary<string, string> resDic, string updateZipDir, string zipFileName)
        {
            string fileData = JsonUtils.ToJson(resDic);
            FileUtils.CreateTextFile(updateZipDir + "/" + UpdateAssetsConst.PathFileName, fileData);

            List<string> zipPaths = new List<string>();
            foreach (string s in resDic.Values)
            {
                Debug.Log("Add :" + s);
                zipPaths.Add(AssetBundlesOutputPath + "/" + s);
            }
            zipPaths.Add(updateZipDir + "/" + UpdateAssetsConst.PathFileName);
            zipPaths.Add(AssetBundlesOutputPath + "/" + UpdateAssetsConst.AssetBundleInfoFileName);

            string zipPath = updateZipDir + "/" + zipFileName;
            ZipUtils.ZipManyFilesOrDictorys(zipPaths, zipPath, null);
            FileUtils.DeleteFile(updateZipDir + "/" + UpdateAssetsConst.PathFileName);
        }
        #endregion
    }
}



